package io.gbznt.modules.buss.quartz;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.gbznt.common.utils.R;
import io.gbznt.modules.buss.entity.BussInspectionPlanEntity;
import io.gbznt.modules.buss.service.BussInspectionPlanService; 

/**

 * @author xcg

 * @version v.0.1

 * @date 2019年5月9日

 */

@RestController
@Component
@RequestMapping("task/test")
public class DynamicTask { 

    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler; 
    @Autowired
    private SchedulerFactoryBean springScheduler;
    @Autowired
    private BussInspectionPlanService bservice;
    

    private ScheduledFuture<?> future; 

    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
       return new ThreadPoolTaskScheduler();
    } 

    @RequestMapping("/startCron")
    public String startCron() {
       String cron = "0/5 * * * * *";
       future = threadPoolTaskScheduler.schedule(new MyRunnable(), new CronTrigger(cron));
       System.out.println("DynamicTask.startCron()");
       return "startCron";
    } 

    @RequestMapping("/stopCron")
    public String stopCron() {

       if (future != null) {
           future.cancel(true);
       }
       System.out.println("DynamicTask.stopCron()");
       return "stopCron";
    }

    @RequestMapping("/changeCron10")
    public String startCron10() {

       stopCron();// 先停止，在开启.
       future = threadPoolTaskScheduler.schedule(new MyRunnable(), new CronTrigger("*/10 * * * * *"));
       System.out.println("DynamicTask.startCron10()");
       return "changeCron10";
    }

    /** 
     * @Description: 添加一个定时任务 
     *  
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置，参考quartz说明文档  
     */  
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();  

    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public static void addJob(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class jobClass, String cron,BussInspectionPlanEntity plan) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任务名，任务组，任务执行类
            String time ="";
            if(plan.getStartTime()!=null){
            	time = plan.getStartTime().toString();
            }
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
            		//巡检任务名称
                	.usingJobData("name", plan.getName())
                	//所属基地
                	.usingJobData("deptId", plan.getDeptId())
                	//巡检人
                	.usingJobData("handler", plan.getHandler())
                	//巡检开始时间
                	.usingJobData("startTime", time)
                	//巡检田块
                	.usingJobData("bussFarmlandInfoIds", plan.getBussFarmlandInfoIds())
                	//巡检任务编号
                	//nm.put("name", plan.get);
                	//巡检任务内容
                	.usingJobData("content", plan.getContent())
                	.usingJobData("createId", plan.getCreateId())
                	
            		
            		.build();
            
            // 触发器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定  
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            Trigger trigger = (Trigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger (jobDetail, trigger);  
            sched.scheduleJob(jobDetail, trigger);

            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
    /** 
     * @Description: 添加一个(无参)定时任务 
     *  
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置，参考quartz说明文档  
     */  

    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public static void addJobnot(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class jobClass, String cron,String key) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任务名，任务组，任务执行类
            String time ="";
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
            		.usingJobData("parkey", key)
                	//巡检任务编号
                	//nm.put("name", plan.get);
            		.build();
            
            // 触发器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定  
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            Trigger trigger = (Trigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger (jobDetail, trigger);  
            sched.scheduleJob(jobDetail, trigger);

            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    } 
    
    /** 
     * @Description: 添加一个读取开关状态定时任务 
     *  
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置，参考quartz说明文档  
     */  

    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public static void switchjob(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class jobClass, String cron,String key) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任务名，任务组，任务执行类
            String time ="";
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
            		.usingJobData("parkey", key)
                	//巡检任务编号
                	//nm.put("name", plan.get);
            		.build();
            
            // 触发器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定  
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            Trigger trigger = (Trigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger (jobDetail, trigger);  
            sched.scheduleJob(jobDetail, trigger);

            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    } 
    
    
    /** 
     * @Description: 移除一个任务 
     *  
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public static void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  

            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

            sched.pauseTrigger(triggerKey);// 停止触发器  
            sched.unscheduleJob(triggerKey);// 移除触发器  
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
    private class MyRunnable implements Runnable {

       @Override
       public void run() {
           System.out.println("DynamicTask.MyRunnable.run()，" + new Date());
       }
    } 
    
    //public static String JOB_NAME = "动态任务调度";  
   // public static String TRIGGER_NAME = "动态任务触发器";  
    //@RequestBody BussFarmingActivityEntity bussFarmingActivity
    public static String JOB_GROUP_NAME = "XLXXCC_JOB_GROUP";  
    public static String TRIGGER_GROUP_NAME = "XLXXCC_JOB_GROUP"; 
    @RequestMapping("/qd/{id}")
    public  R qd(@PathVariable("id") String id) {
        try {  
        	BussInspectionPlanEntity plan = bservice.getById(id);
            System.out.println("【系统启动】...");   
            String cron = "";
            if(plan.getFrequencyFormulatype().equals("分")){
            	 cron = "0 */"+plan.getFrequencyFormula()+" * * * ?";
            }else if(plan.getFrequencyFormulatype().equals("时")){
            	 cron = "* * 0-"+plan.getFrequencyFormula()+" * * ?";
            }else if(plan.getFrequencyFormulatype().equals("天")){
            	 cron = "* * 0 "+plan.getFrequencyFormula()+" * ?";
            }else if(plan.getFrequencyFormulatype().equals("周")){
            	 cron = "0 0 0 ? * "+plan.getFrequencyFormula()+" ";
            }
            
            //jobName 任务名  reigname 触发器名称都设置为计划名称
            DynamicTask.addJob(plan.getId(), JOB_GROUP_NAME, plan.getId(), TRIGGER_GROUP_NAME, MyJob.class, cron,plan);    
        } catch (Exception e) {  
            e.printStackTrace();  
            return R.error();
        }  
        return R.ok();
    }
    
    @RequestMapping("/remove/{jobname}")
    public  R remove(@PathVariable("jobname") String jobname) {
        try {  

            //Thread.sleep(6000);    
            System.out.println("【移除定时】开始...");    
            DynamicTask.removeJob(jobname, JOB_GROUP_NAME, jobname, TRIGGER_GROUP_NAME);    
            System.out.println("【移除定时】成功");    
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return R.ok();
    }
    
    @RequestMapping("/ck")
    public List<QuartzJobsVO> getAllJobs() {
    	 List<QuartzJobsVO> quartzJobsVOList = new ArrayList<>();
         try {
             //获取Scheduler
        	 Scheduler scheduler = schedulerFactory.getScheduler();  
             //Scheduler scheduler = springScheduler.getScheduler();
             //再获取Scheduler下的所有group
             List<String> triggerGroupNames = scheduler.getTriggerGroupNames();
             System.out.println("长度-------"+triggerGroupNames.size());
             for (String groupName : triggerGroupNames) {
                 //组装group的匹配，为了模糊获取所有的triggerKey或者jobKey
                 GroupMatcher groupMatcher = GroupMatcher.groupEquals(groupName);
                 //获取所有的triggerKey
                 Set<TriggerKey> triggerKeySet = scheduler.getTriggerKeys(groupMatcher);
                 for (TriggerKey triggerKey : triggerKeySet) {
                     //通过triggerKey在scheduler中获取trigger对象
                	 Trigger trigger = (Trigger) scheduler.getTrigger(triggerKey);
                    // CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                     //获取trigger拥有的Job
                     JobKey jobKey = trigger.getJobKey();
                     JobDetailImpl jobDetail = (JobDetailImpl) scheduler.getJobDetail(jobKey);
                     //组装页面需要显示的数据
                     QuartzJobsVO quartzJobsVO = new QuartzJobsVO();
                     quartzJobsVO.setGroupName(groupName);
                     quartzJobsVO.setJobDetailName(jobDetail.getName());
                   /*  quartzJobsVO.setJobCronExpression(trigger.getCronExpression());
                     quartzJobsVO.setTimeZone(trigger.getTimeZone().getID());*/
                     quartzJobsVOList.add(quartzJobsVO);
                 }
             }
         } catch (Exception e) {
             //log.error("获取定时任务信息出错", e);
         }
         return quartzJobsVOList;
     }
    	 
    
    
}

